package com.lzp.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lzp.mapper.*;
import com.lzp.pojo.*;
import com.lzp.pojo.vo.CommentLevelCountsVO;
import com.lzp.pojo.vo.ItemCommentVO;
import com.lzp.pojo.vo.SearchItemsVO;
import com.lzp.pojo.vo.ShopcartVO;
import com.lzp.service.ItemService;
import com.lzp.utils.DesensitizationUtil;
import com.lzp.utils.PagedGridResult;
import com.lzp.utils.enums.CommentLevel;
import com.lzp.utils.enums.Yes0rNo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;

/**
 * 商品业务实现
 *
 * @author dtyy
 * @date 2020/8/4
 */
@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ItemsMapper itemsMapper;

    @Autowired
    private ItemsImgMapper itemsImgMapper;

    @Autowired
    private ItemsSpecMapper itemsSpecMapper;

    @Autowired
    private ItemsParamMapper itemsParamMapper;

    @Autowired
    private ItemsCommentsMapper itemsCommentsMapper;

    @Autowired
    private ItemsMapperCustom itemsMapperCustom;

    /**
     * 根据商品id查询详情
     *
     * @param itemId 商品id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Items getItemById(String itemId) {
        return itemsMapper.selectByPrimaryKey(itemId);
    }

    /**
     * 根据商品id查询商品图片列表
     *
     * @param itemId 商品id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<ItemsImg> listItemImg(String itemId) {

        Example itemImgExp = new Example(ItemsImg.class);
        Example.Criteria criteria = itemImgExp.createCriteria();
        criteria.andEqualTo("itemId", itemId);

        return itemsImgMapper.selectByExample(itemImgExp);
    }

    /**
     * 根据商品id查询商品规格
     *
     * @param itemId 商品id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<ItemsSpec> listItemSpec(String itemId) {
        Example itemSpecExp = new Example(ItemsSpec.class);
        Example.Criteria criteria = itemSpecExp.createCriteria();
        criteria.andEqualTo("itemId", itemId);

        return itemsSpecMapper.selectByExample(itemSpecExp);
    }

    /**
     * 根据商品id查询商品参数
     *
     * @param itemId 商品id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ItemsParam getItemParam(String itemId) {
        Example itemParamExp = new Example(ItemsParam.class);
        Example.Criteria criteria = itemParamExp.createCriteria();
        criteria.andEqualTo("itemId", itemId);

        return itemsParamMapper.selectOneByExample(itemParamExp);
    }

    /**
     * 查询商品评价数量
     * <p>
     * 拆分的思想，采用单表查询。联合查询影响性能
     *
     * @param itemId 商品id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public CommentLevelCountsVO getCommentCounts(String itemId) {

        // 构建查询参数BO
        Integer goodCounts = getCommentCount(itemId, CommentLevel.GOOD.getCode());
        Integer normalCounts = getCommentCount(itemId, CommentLevel.NORMAL.getCode());
        Integer badCounts = getCommentCount(itemId, CommentLevel.BAD.getCode());
        Integer totalCounts = goodCounts + normalCounts + badCounts;

        // 封装VO
        CommentLevelCountsVO countsVO = new CommentLevelCountsVO();
        countsVO.setGoodCounts(goodCounts);
        countsVO.setNormalCounts(normalCounts);
        countsVO.setBadCounts(badCounts);
        countsVO.setTotalCounts(totalCounts);

        return countsVO;
    }

    /**
     * 获取某商品某级别的评价数量
     *
     * @param itemId 商品id
     * @param level  评价级别
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    Integer getCommentCount(String itemId, Integer level) {
        ItemsComments condition = new ItemsComments();
        condition.setItemId(itemId);
        if (level != null) {
            condition.setCommentLevel(level);
        }
        // selectCount -- 统计数量
        return itemsCommentsMapper.selectCount(condition);
    }

    /**
     * 查询商品评价
     *
     * @param itemId   商品id
     * @param level    评价级别
     * @param page     当前页
     * @param pageSize 每页条数
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedGridResult queryPagedComments(String itemId, Integer level, Integer page, Integer pageSize) {

        // 构建查询参数map
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("itemId", itemId);
        paramsMap.put("level", level);

        // 分页：在查询前使用分页插件，统一拦截sql，提供分页功能
        // 属于假分页，查询整个list，不如limit（真分页）
        PageHelper.startPage(page, pageSize);

        // 查表
        List<ItemCommentVO> list = itemsMapperCustom.queryItemComments(paramsMap);

        // 昵称脱敏
        for (ItemCommentVO vo : list) {
            vo.setNickname(DesensitizationUtil.desenseDisplay(vo.getNickname()));
        }

        // 返回分页数据
        return wrapPagedGrid(list, page);
    }

    /**
     * 分页结果处理
     *
     * @param list 所有记录
     * @param page 第几页
     * @return
     */
    private PagedGridResult wrapPagedGrid(List<?> list, Integer page) {
        PageInfo<?> pageInfo = new PageInfo<>(list);
        PagedGridResult result = new PagedGridResult();
        result.setPage(page); // 当前第几页
        result.setRows(list); // 每页内容
        result.setTotal(pageInfo.getPages()); // 总页数
        result.setRecords(pageInfo.getTotal()); // 总记录数

        return result;
    }

    /**
     * 搜索商品
     *
     * @param keywords 关键词
     * @param sort     排序规则
     * @param page     当前页
     * @param pageSize 每页条数
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedGridResult searchItems(String keywords, String sort, Integer page, Integer pageSize) {
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("keywords", keywords);
        paramsMap.put("sort", sort);

        PageHelper.startPage(page, pageSize);
        List<SearchItemsVO> list = itemsMapperCustom.searchItems(paramsMap);
        return wrapPagedGrid(list, page);
    }

    /**
     * 根据第三分类查询商品列表
     *
     * @param catId    第三分类id
     * @param sort     排序规则
     * @param page     当前页
     * @param pageSize 每页条数
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedGridResult searchItems(Integer catId, String sort, Integer page, Integer pageSize) {
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("catId", catId);
        paramsMap.put("sort", sort);

        PageHelper.startPage(page, pageSize);
        List<SearchItemsVO> list = itemsMapperCustom.searchItemsByThirdCatId(paramsMap);
        return wrapPagedGrid(list, page);
    }

    /**
     * 根据商品规格id查询商品数据
     *
     * @param specIds 规格字符串
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<ShopcartVO> queryItemsBySpecIds(String specIds) {
        String[] ids = specIds.split(",");

        List<String> specIdsList = new ArrayList<>();
        Collections.addAll(specIdsList, ids);

        return itemsMapperCustom.queryItemsBySpecIds(specIdsList);
    }

    /**
     * 根据规格id查询规格数据以及商品id
     *
     * @param specId 规格id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ItemsSpec queryItemSpecBySpecId(String specId) {
        return itemsSpecMapper.selectByPrimaryKey(specId);
    }

    /**
     * 根据商品id查询商品主图
     *
     * @param itemId 商品id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public String queryItemMainImgByItemId(String itemId) {
        ItemsImg itemsImg = new ItemsImg();
        itemsImg.setItemId(itemId);
        itemsImg.setIsMain(Yes0rNo.YES.getCode());
        ItemsImg result = itemsImgMapper.selectOne(itemsImg);
        return result != null ? result.getUrl() : "";
    }

    /**
     * 减少库存
     *
     * @param specId    规格id
     * @param buyCounts 购买数量
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void decreaseItemSpecStock(String specId, int buyCounts) {
        // synchronized 不推荐使用，集群下无用，性能低下
        // 锁数据库: 不推荐，导致数据库性能低下
        // 分布式锁 zookeeper redis
        // LockUtil.lock();
        // dosomething
        // LockUtil.unlock();
        int result = itemsMapperCustom.decreaseItemSpecStock(specId, buyCounts);
        if (result != 1) {
            throw new RuntimeException("库存不足");
        }
    }

}
